﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.CodeDom.Compiler;
using Parallel3M.parallel3m.framework;
using System.Xml;

namespace Parallel3M.parallel3m.handler
{
    public class CSharpCodeCompileHandler:ParallelHandler
    {
        /*
        <payload timestamp='' routeTag='*' domain='*' type='request' handlerid='CSHARP_COMPILE' access='Public' language='c#'>
          <request>
            
          </request>
          <response/>
        </payload>        
        */

        public CSharpCodeCompileHandler()
        {
            handlerid = ParallelSystemHandlersConst.CSHARP_COMPILER_HANDLER;
            handlername = "CSHAPR CODE COMPILE";
            handlerdefine = "<handler><input><code/></input><output/></handler>";

        }

        /*
         * Funcaton Name as the dll Name
         * Source code
         */ 

        public override string handle(ParallelPayload payload)
        {
            String output = "";
            Hashtable parameters = new Hashtable();
            // Create an XmlReader
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(payload.request);
            XmlNode requestNode = doc.ChildNodes[0];
            XmlAttributeCollection atts = requestNode.Attributes;
            foreach (XmlAttribute att in atts)
            {
                parameters.Add(att.Name, att.Value);
            }
            
            try
            {
                //get the input parameters
                string code = requestNode.InnerXml.ToString();
                string assembly = (String)parameters["assembly"];

                //compile using javac.exe
                String dllFile = ParallelContext.classpath + "\\" + assembly + ".dll";

                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
                String[] referenceAssemblies = { "System.dll","System.Core.dll","Parallel3M.dll" };
                CompilerParameters cp = new CompilerParameters(referenceAssemblies,
                                                               dllFile, false);
                // Generate an executable rather than a DLL file.
                cp.GenerateExecutable = false;

                // Invoke compilation.
                CompilerResults cr = provider.CompileAssemblyFromSource(cp, code);

                //get the output
                if (cr.Errors.Count > 0)
                {
                    // Display compilation errors.                
                    foreach (CompilerError ce in cr.Errors)
                    {
                        output += "<compileerror>" + ce.ToString() + "</compilerror>";
                    }
                }
                else
                {
                    output += "<compile>no</compile>";
                }
            }
            catch (Exception e)
            {
                e.ToString();
            }

            return output;
        }
    }
}
